﻿using System;
using System.Linq;
using System.Net.Sockets;
using Newtonsoft.Json;
using hq;
using hcache;
using hentity;
using hutil;

namespace hconnect {
    public abstract class SocketZtTaskConnect :ZtTaskConnect {
        private Socket socket = null;
         public bool sendTask(BaseTask task ,int begin) {
            task = ( BaseTask ) task.Clone();
        
           fileAll("{0}发送任务{1}" ,this.className ,ObjStrUtil.mySerializeObject(task));
            return send(task ,begin);
        }
         protected virtual bool send(BaseTask task ,int begin ) {
            throw new Exception(this.className + "的 send方法未实现");
        }
         protected bool Send(byte[] packet) {//发报文
            if( socket == null ) {
                return false;
            }
            try {
                int size = socket.Send(packet);
                bool send = size == packet.Length;
                if( !send ) {
                    forceDisConnection();
                }
                return send;
            } catch( Exception e ) {
                forceDisConnection();
                 throw e;
            }
        }
        protected byte[] ReadTelex(int bufferSize) {//接收报文
            if( socket == null ) {
                return null;
            }
            byte[] array = new byte[bufferSize];
            try {
              
                int count = socket.Receive(array);
                return array.Take(count).ToArray<byte>();
            } catch( Exception e ) {
                forceDisConnection();
                throw e;
            }
         }
        protected virtual void forceDisConnection() {
            if( socket == null ) {
                return;
            }
            try {
                socket.Close();
                socket.Dispose();
            } catch {
                throw new Exception("关闭连接异常" + className + ip + ":" + port);
            }
            fileAll("成功断开连接" + className + ip + ":" + port);
            socket = null;
        }
       
        public virtual bool afterConnect() {
            return true;
        }
        protected override bool reConnect() {
            if( TaskCacheDB.test ) {
                return true;
            }
            lock( className ) {
                if( !noConn() ) {
                    return false;
                }
                forceDisConnection();
                socket = new Socket(AddressFamily.InterNetwork ,SocketType.Stream ,ProtocolType.Tcp);
                socket.ReceiveTimeout = 4000;
                socket.SendTimeout = 4000;
                socket.Connect(ipEndPoint);
                afterConnect();
                if( noConn() ) {
                    forceDisConnection();
                }
            }
           
            return true;
        }
        protected bool noConn() {
            if( TaskCacheDB.test ) {
                return false;
            }
            if( socket == null ) {
                return true;
            }
            return !socket.Connected;
        }
     }
}
